﻿using System.Linq;
using System.Net.Http;

namespace DotNetStar.OpenSDK
{
    /// <summary>
    /// 表示定义 api 请求的基类。这是一个抽象类。
    /// </summary>
    /// <typeparam name="TResponse">表示 api 返回的响应对象。</typeparam>
    public abstract class ApiRequest<TResponse>
    {
        /// <summary>
        /// 使用 GET 方式初始化和指定的请求 url 地址 <see cref="ApiRequest{TResponse}"/> 类的新实例。
        /// </summary>
        /// <param name="requestUrl">请求不带任何参数的 api 地址。</param>
        public ApiRequest(string requestUrl) => this.RequestUrl = requestUrl;

        /// <summary>
        /// 获取请求 api 的 url 地址字符串。
        /// </summary>
        [ArgumentIgnore]
        public string RequestUrl { get; }

        /// <summary>
        /// 当参数创建时触发的事件。重写此方法来重构创建参数的过程。
        /// 默认返回 <see cref="KeyValueCollection.ToString"/> 方法的结果，查看文档了解详细说明和用法。
        /// </summary>
        /// <remarks>
        /// 这是一个嵌入点，可在重写此方法时根据自己的业务更改创建参数的逻辑。
        /// </remarks>
        /// <param name="keyValue"> <see cref="KeyValueCollection"/> 实例的动态对象，查看文档了解用法。</param>
        /// <returns>默认返回 <see cref="KeyValueCollection.ToString"/> 方法的结果。在派生类重写时可重新定义一个可以被最终 HTTP 方法识别的返回值。</returns>
        public virtual dynamic OnArgumentsCreating(dynamic keyValue) => keyValue.str();

        /// <summary>
        /// 处理自定义请求结果的回调。默认将从 <see cref="HttpResponseMessage.Content"/> 读取 JSON 字符串形式并进行反序列化成 <see cref="TResponse"/> 类型。
        /// </summary>
        /// <param name="httpResponse">Http 请求响应的 <see cref="HttpResponseMessage"/> 实例。</param>
        /// <returns>自定义的处理结果。</returns>
        public virtual TResponse ResponseHandler(HttpResponseMessage httpResponse) => SDK.Deserialize<TResponse>(httpResponse.GetContentAsString());
    }
}
